package worker

import (
	"errors"
	"fmt"
	"log"
	"luiz/crawler/engine"
	"luiz/crawler/ziru/parser"
	"luiz/crawler_distributed/config"
)

type SerializedParser struct {
	Name string
	Args interface{}
}

type Request struct {
	Url    string
	Parser SerializedParser
}
type ParseResult struct {
	Items   []engine.Item
	Request []Request
}

func SerializeRequest(r engine.Request) Request {
	name, args := r.Parser.Serialize()
	return Request{
		Url:    r.Url,
		Parser: SerializedParser{Name: name, Args: args},
	}
}
func SerializeResult(r engine.ParseResult) ParseResult {
	result := ParseResult{
		Items: r.Items,
	}
	for _, req := range r.Request {
		result.Request = append(result.Request, SerializeRequest(req))
	}
	return result
}
func DeserializeRequest(r Request) (engine.Request, error) {
	e, err := deParser(r.Parser)
	if err != nil {
		return engine.Request{}, err
	}
	return engine.Request{
		Url:    r.Url,
		Parser: e,
	}, nil
}
func deParser(p SerializedParser) (engine.Parser, error) {
	switch p.Name {
	case config.ParseCityList:
		return engine.NewFuncParser(parser.ParseCityList, config.ParseCityList), nil
	case config.ParseHezuList:
		return engine.NewFuncParser(parser.ParseHezuList, config.ParseHezuList), nil
	case config.PreaseUrls:
		return engine.NewFuncParser(parser.PreaseUrls, config.PreaseUrls), nil
	case config.PreaseArea:
		return engine.NewFuncParser(parser.PreaseArea, config.PreaseArea), nil
	case config.ProfileParse:
		if userName, ok := p.Args.(string); ok {
			return parser.NewProfileParser(userName), nil
		} else {
			return nil, fmt.Errorf("invalid args:%v", p.Args)
		}

	default:
		return nil, errors.New("unknow")

	}
}
func DeResult(r ParseResult) engine.ParseResult {
	result := engine.ParseResult{Items: r.Items}

	for _, req := range r.Request {
		request, err := DeserializeRequest(req)
		if err != nil {
			log.Printf("error:%v", err)
			continue
		}
		result.Request = append(result.Request, request)
	}
	return result
}
